import { Graph, Dom, Shape } from '@antv/x6'
import dagre from 'dagre'
import './shape'
export default class FlowGraph {
  // constructor () {}
  initGraph (graphId) {
    this.graph = new Graph({
      container: graphId,
      width: '100%',
      height: '100%',
      grid: {
        size: 10, // 网格大小 10px
        visible: true // 渲染网格背景
      },
      scroller: true, // 是否显示滚动条
      interacting: {
        nodeMovable: true // 节点是否可以被移动
      },
      // ctrl + 滚轮缩放
      mousewheel: {
        enabled: true,
        modifiers: ['ctrl', 'meta'], // 修饰键('alt'、'ctrl'、'meta'、'shift')
        minScale: 0.5, // 最小的缩放级别
        maxScale: 2 // 最大的缩放级别
      },
      // 点选/框选
      selecting: {
        enabled: true, // 是否启用点选/框选
        multiple: true, // 是否启用点击多选
        rubberband: true, // 是否启用框选
        movable: false, // 在多选情况下，选中的节点是否一起移动
        showNodeSelectionBox: true // 是否显示节点的选择框
      },
      // 路由规则
      connecting: {
        router: {
          // name: 'orth', // 关系路由
          name: 'er', // 关系路由
          args: {
            offset: 25, // 路由的第一个点和最后一个点与节点之间的距离，当取值为 'center' 时，节点距离的中心作为路由点坐标
            direction: 'H', // 路由方向，缺省时将自动选择最优方向
            // startDirections: ['right'],
            // endDirections: ['left']
          }
        }
      }
    })
  }

  // 监听自定义事件
  setup () {
    this.graph.on('node:delete', ({ e, node }) => {
      e.stopPropagation()
      this.graph.freeze()
      this.graph.removeCell(node)
      FlowGraph.layout('LR')
    })
    this.graph.on('node:image', ({ e, node }) => {
      e.stopPropagation()
      console.log(e, node)
    })
  }

  // createNode (rank, name, image) {
  //   return this.graph.createNode({
  //     shape: 'org-node',
  //     attrs: {
  //       '.image': { xlinkHref: image },
  //       '.rank': {
  //         text: Dom.breakText(rank, { width: 100, height: 45 })
  //       },
  //       '.name': {
  //         text: Dom.breakText(name, { width: 160, height: 45 })
  //       }
  //     }
  //   })
  // }

  createNode (item) {
    return this.graph.createNode(item)
  }

  createEdge(item) {
    return this.graph.createEdge(item)
  }

  // 清空画布并添加用指定的节点/边
  resetCells (nodes, edges) {
    this.graph.resetCells([...nodes, ...edges])
  }

  centerContent () {
    this.graph.centerContent()
  }

  zoomTo (num) {
    this.graph.zoomTo(num)
  }

  // 自动布局
  layout (dir) {
    const nodes = this.graph.getNodes()
    const edges = this.graph.getEdges()
    const g = new dagre.graphlib.Graph()
    g.setGraph({ rankdir: dir, nodesep: 16, ranksep: 120 })
    g.setDefaultEdgeLabel(() => ({}))

    const width = 150
    const height = 250
    nodes.forEach((node) => {
      g.setNode(node.id, { width, height })
    })

    edges.forEach((edge) => {
      const source = edge.getSource()
      const target = edge.getTarget()
      g.setEdge(source.cell, target.cell)
    })

    dagre.layout(g)

    // this.graph.freeze()

    g.nodes().forEach((id) => {
      const node = this.graph.getCell(id)
      if (node) {
        const pos = g.node(id)
        node.position(pos.x, pos.y)
      }
    })
    return
    edges.forEach((edge) => {
      const source = edge.getSourceNode()
      const target = edge.getTargetNode()
      const sourceBBox = source.getBBox()
      const targetBBox = target.getBBox()

      // console.log(sourceBBox, targetBBox)

      if ((dir === 'LR' || dir === 'RL') && sourceBBox.y !== targetBBox.y) {
        const gap = dir === 'LR' ? targetBBox.x - sourceBBox.x - sourceBBox.width : -sourceBBox.x + targetBBox.x + targetBBox.width
        const fix = dir === 'LR' ? sourceBBox.width : 0
        const x = sourceBBox.x + fix + gap / 2
        edge.setVertices([
          { x, y: sourceBBox.center.y },
          { x, y: targetBBox.center.y }
        ])
      } else if ((dir === 'TB' || dir === 'BT') && sourceBBox.x !== targetBBox.x) {
        const gap = dir === 'TB' ? targetBBox.y - sourceBBox.y - sourceBBox.height : -sourceBBox.y + targetBBox.y + targetBBox.height
        const fix = dir === 'TB' ? sourceBBox.height : 0
        const y = sourceBBox.y + fix + gap / 2
        edge.setVertices([
          { x: sourceBBox.center.x, y },
          { x: targetBBox.center.x, y }
        ])
      } else {
        edge.setVertices([])
      }
    })

    // this.graph.unfreeze()
  }

  // 销毁
  destroy () {
    this.graph.dispose()
  }

  // 数据导出
  exportData () {
    return this.graph.toJSON()
  }

  // 序列化数据
  importData (data) {
    return this.graph.fromJSON(data)
  }
}
